import java.io.*;
import java.util.*;

//用户类
class User {
    String studentId;
    String name;
    String password = "123456"; // 默认密码
    double balance = 0;
    List<Transaction> transactions = new ArrayList<>();
    boolean isLost = false; // 卡是否挂失
    boolean pendingLoss; // 等待挂失确认
    boolean pendingRecovery; // 等待解挂确认
    double dailyConsumption = 0; // 今日消费
    final double DAILY_LIMIT = 50; // 每日消费限制

    private static final String FILE_PATH = "C:\\Users\\lemon\\Desktop\\java大作业\\dazuoye1\\user_data.txt";
    //private static final String FILE_PATH = "user_data.txt"; // 文件在项目根目录

    public User(String studentId, String name, String password, double balance, boolean isLost, double dailyConsumption) {
        this.studentId = studentId;
        this.name = name;
        this.password = password;
        this.balance = balance;
        this.isLost = isLost;
        this.dailyConsumption = dailyConsumption;
        this.pendingLoss = false;
        this.pendingRecovery = false;

    }

    //输出名字
    public String getName() {

        return name;
    }

    //密码验证
    public boolean verifyPassword(String inputPassword) {

        return password.equals(inputPassword);
    }

    public void recharge(double amount) {
        if (amount <= 500) {
            balance += amount;
            System.out.println("充值成功！当前余额：" + balance);
            saveUserData();
        } else {
            System.out.println("充值金额超出限制！");
        }
    }

    public boolean consume(double amount, String location) {
        if (isLost) {
            System.out.println("校园卡已挂失，无法消费。");
            return false;
        }
        if (balance < amount) {
            System.out.println("余额不足，消费失败。");
            return false;
        }
        if (dailyConsumption + amount > DAILY_LIMIT) {
            System.out.print("超出每日消费限制，请输入密码继续消费：");
            Scanner scanner = new Scanner(System.in);
            String inputPassword = scanner.nextLine();
            if (!inputPassword.equals(password)) {
                System.out.println("密码错误，消费失败。");
                return false;
            }
        }
        balance -= amount;
        dailyConsumption += amount;
        transactions.add(new Transaction(amount, new Date(), location));
        System.out.println("消费成功！当前余额：" + balance);
        System.out.println("当前交易记录：");
        for (Transaction transaction : transactions) {
            System.out.println(transaction);
        }
        saveUserData();
        return true;
    }

    //修改密码
    public void modifyPassword(String newPassword) {
        password = newPassword;
        System.out.println("密码修改成功！");
        saveUserData();
    }


    //挂失
    public void requestLoss() {
        pendingLoss = true;
        System.out.println("校园卡挂失请求已提交，请等待管理员确认。");

    }
    public void confirmLoss() {
        if (pendingLoss) {
            isLost = true;
            pendingLoss = false;
            System.out.println("校园卡已挂失，已禁止使用。");
            saveUserData();
        } else {
            System.out.println("没有挂失请求。");
        }
    }

    //解挂
    public void requestRecovery() {
        pendingRecovery = true;
        System.out.println("校园卡解挂请求已提交，请等待管理员确认。");

    }
    public void confirmRecovery() {
        if (pendingRecovery) {
            isLost = false;
            pendingRecovery = false;
            saveUserData();
            System.out.println("校园卡已解挂，可以使用。");
        } else {
            System.out.println("没有解挂请求。");
        }
    }



    //支出
    public void showBalance() {
        if (balance < 10) {
            System.out.println("余额不足10元，请及时充值！");
        }
    }

    //查询消费
    public void showTransactions(Date startDate, Date endDate, String location) {
        for (Transaction transaction : transactions) {
            if (transaction.date.after(startDate) && transaction.date.before(endDate) &&
                    transaction.location.equals(location)) {
                System.out.println(transaction);
            }
        }
    }


//保存用户数据
public void saveUserData() {
    List<String> lines = new ArrayList<>();
    Set<String> userTransactions = new HashSet<>(); // 当前用户的交易记录，去重
    Set<String> allTransactions = new HashSet<>();  // 所有用户的交易记录，去重

    // 1. 读取现有数据
    try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
            // 如果这一行是交易记录，添加到全局交易记录集合中
            if (line.contains(",")) {  // 假设每行包含 "," 为交易记录
                allTransactions.add(line);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    String userData = studentId + "," + name + "," + password + "," + balance + "," + isLost + "," + dailyConsumption;
    int userIndex = -1; // 记录用户的行数
    boolean userUpdated = false;

    // 查找并替换对应用户的数据
    for (int i = 0; i < lines.size(); i++) {
        if (lines.get(i).startsWith(studentId + ",")) {
            lines.set(i, userData);  // 更新用户数据
            userIndex = i;
            userUpdated = true;
            break;
        }
    }

    // 如果没有找到用户，说明是新用户，直接添加
    if (!userUpdated) {
        lines.add(userData); // 新用户信息
        userIndex = lines.size() - 1;
    }

    // 2. 收集并去重当前用户的交易记录
    for (Transaction transaction : transactions) {
        String transactionRecord = transaction.amount + "," + transaction.date.getTime() + "," + transaction.location;
        // 只有当前交易记录不在所有交易记录中，才添加
        if (!allTransactions.contains(transactionRecord)) {
            userTransactions.add(transactionRecord);  // 将当前用户的去重交易记录添加
            allTransactions.add(transactionRecord);  // 同时更新全局去重交易记录集合
        }
    }

    // 3. 写回文件，确保每个用户的数据和交易记录只写一次
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH))) {
        boolean userDataWritten = false; // 标记是否写入了用户数据
        boolean transactionWritten = false; // 标记是否写入了交易记录

        for (int i = 0; i < lines.size(); i++) {
            // 写入用户数据
            writer.write(lines.get(i));
            writer.newLine();

            // 如果是当前用户，写入交易记录
            if (i == userIndex && !transactionWritten) {
                // 写入去重后的交易记录
                for (String transaction : userTransactions) {
                    writer.write(transaction);
                    writer.newLine();
                }
                transactionWritten = true; // 交易记录只写入一次
            }
        }

        for (Transaction transaction : transactions) {
            String transactionRecord = transaction.amount + "," + transaction.date.getTime() + "," + transaction.location;
            // 只有当前交易记录不在所有交易记录中，才添加
            if (!allTransactions.contains(transactionRecord)) {
                userTransactions.add(transactionRecord);  // 将当前用户的去重交易记录添加
                allTransactions.add(transactionRecord);  // 同时更新全局去重交易记录集合
            }
        }

        // 如果当前用户没有写入交易记录（可能没有交易），则写入
        if (!transactionWritten) {
            for (String transaction : userTransactions) {
                writer.write(transaction);
                writer.newLine();
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}
//public void saveUserData() {
//    List<String> lines = new ArrayList<>();
//    List<String> userTransactions = new ArrayList<>();
//
//    // 1. 读取现有数据
//    try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
//        String line;
//        while ((line = reader.readLine()) != null) {
//            lines.add(line);
//        }
//    } catch (IOException e) {
//        e.printStackTrace();
//    }
//
//    // 2. 修改数据
//    String userData = studentId + "," + name + "," + password + "," + balance + "," + isLost + "," + dailyConsumption;
//    int userIndex = -1; // 使用-1来表示未找到用户
//    boolean userUpdated = false;
//
//    // 查找并替换对应用户的数据
//    for (int i = 0; i < lines.size(); i++) {
//        if (lines.get(i).startsWith(studentId + ",")) {
//            lines.set(i, userData);
//            userIndex = i; // 记录用户的行数
//            userUpdated = true;
//            break;
//        }
//    }
//
//    // 如果没有找到对应的用户，可以选择添加
//    if (!userUpdated) {
//        lines.add(userData); // 新用户信息
//        userIndex = lines.size() - 1; // 记录最后一行
//    }
//
//    // 3. 收集用户的交易记录
//    for (Transaction transaction : transactions) {
//        userTransactions.add(transaction.amount + "," + transaction.date.getTime() + "," + transaction.location);
//    }
//
//    // 4. 写回文件
//    try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH))) {
//        boolean userDataWritten = false; // 标记用户数据是否已写入
//        for (int i = 0; i < lines.size(); i++) {
//            // 写入用户信息
//            writer.write(lines.get(i));
//            writer.newLine();
//
//            // 写入用户的交易记录，仅在用户数据后第一次写入
//            if (i == userIndex && !userDataWritten) {
//                // 使用一个 Set 来确保交易记录的唯一性
//                Set<String> uniqueTransactions = new HashSet<>(userTransactions);
//                for (String transaction : uniqueTransactions) {
//                    writer.write(transaction);
//                    writer.newLine();
//                }
//                writer.newLine(); // 添加一个空行以分隔用户数据
//                userDataWritten = true; // 标记交易记录已写入
//            }
//        }
//    } catch (IOException e) {
//        e.printStackTrace();
//    }
//}
//读取用户数据
public static List<User> loadUserData() {
    // 读取文件，如果没有则创建一个
    File file = new File(FILE_PATH);
    List<User> users = new ArrayList<>();
    if (!file.exists()) {
        try {
            file.createNewFile(); // 创建新文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        return users; // 文件创建后直接返回
    }

    try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.trim().isEmpty()) {
                continue; // 跳过空行
            }

            // 读取用户信息
            String[] data = line.split(",");
            if (data.length >= 6) {
                String studentId = data[0];
                String name = data[1];
                String password = data[2];
                double balance = Double.parseDouble(data[3]);
                boolean isLost = Boolean.parseBoolean(data[4]);
                double dailyConsumption = Double.parseDouble(data[5]);

                User user = new User(studentId, name, password, balance, isLost, dailyConsumption);

                // 清空交易记录以准备下一个用户的交易
                user.transactions.clear();

                // 读取该用户的交易记录
                String transactionLine; // 新变量用于交易记录的读取
                Set<String> seenTransactions = new HashSet<>(); // 使用 HashSet 来存储交易记录的唯一标识符
                while ((transactionLine = reader.readLine()) != null) {
                    if (transactionLine.trim().isEmpty() || transactionLine.startsWith("User:")) {
                        break; // 遇到空行或下一个用户信息则停止读取当前用户的交易记录
                    }
                    String[] transData = transactionLine.split(",");
                    if (transData.length < 3) {
                        continue; // 防止数据格式不正确
                    }

                    double amount = Double.parseDouble(transData[0]);
                    Date date = new Date(Long.parseLong(transData[1]));
                    String location = transData[2];

                    // 构造一个唯一的交易标识符，使用 amount + date + location 来标识交易
                    String transactionKey = amount + "," + date.getTime() + "," + location;

                    // 检查交易是否已存在
                    if (!seenTransactions.contains(transactionKey)) {
                        seenTransactions.add(transactionKey); // 添加到集合中
                        user.transactions.add(new Transaction(amount, date, location)); // 添加唯一交易
                    }
                }

                users.add(user); // 添加用户到列表
            }
        }
    } catch (FileNotFoundException e) {
        System.err.println("文件未找到: " + FILE_PATH);
        e.printStackTrace();
    } catch (IOException e) {
        System.err.println("读取文件时出错: " + e.getMessage());
        e.printStackTrace();
    } catch (NumberFormatException e) {
        System.err.println("数据格式错误: " + e.getMessage());
        e.printStackTrace();
    }
    return users;
}    @Override
    public String toString() {
        return
                "学生学号:" + studentId  +
                ", 学生名字:" + name +
                ", 余额:" + balance +
                ", 挂失状态:" + isLost +
                ", 今日消费:" + dailyConsumption;
    }
}




//交易
class Transaction {
    double amount;
    Date date;
    String location;

    public Transaction(double amount, Date date, String location) {
        this.amount = amount;
        this.date = date;
        this.location = location;
    }
    // 添加访问器方法
    public double getAmount() {
        return amount;
    }

    public Date getDate() {
        return date;
    }

    public String getLocation() {
        return location;
    }
    @Override
    public String toString() {
        return "消费金额: " + amount + ", 日期: " + date + ", 地点: " + location;
    }
}